#include <setjmp.h>
#include "globals.h"
#define	RTT_DEBUG

static struct rtt_info   rttinfo;
static int rttinit = 0;

static void sig_alrm(int signo);
static sigjmp_buf jmpbuf;

ssize_t
dg_send_recv(int fd, datagram* dg_ptr, int flags, datagram_list *head)
{
	struct itimerval tout_val;
	datagram recvhdr;
	ssize_t	n = 0;
	int temp_sec = 0;
	int time_sec = 0;
	int time_m_sec = 0;
	time_t timer = time(NULL);
    
    printf("current time is %s", ctime(&timer));
    
    rtt_d_flag = 1;

	if (rttinit == 0) {
		rtt_init(&rttinfo);	// first time we're called 
		rttinit = 1;
	}

	Signal(SIGALRM, sig_alrm);
	rtt_newpack(&rttinfo);		// initialize for this packet 

sendagain:
#ifdef	RTT_DEBUG
	fprintf(stderr, "send %4d: ", dg_ptr->seq_num);
#endif

        send(fd, dg_ptr, sizeof(*dg_ptr), flags);
        printf("%s ACK sent to Server\n", CLI_LOG);

	/* Convert milli seconds to seconds and micro seconds and starting the timer */
	temp_sec = rtt_start(&rttinfo);
	if (temp_sec >= 1000) {
		time_sec = temp_sec / 1000;
	}
	time_m_sec = temp_sec % 1000;

    tout_val.it_interval.tv_sec = 0;
    tout_val.it_interval.tv_usec = 0;
    tout_val.it_value.tv_sec = time_sec;
	tout_val.it_value.tv_usec = time_m_sec;
    
    printf("\nTIMER BITCHES: %d %d\n", tout_val.it_value.tv_sec,
            tout_val.it_value.tv_usec);

    setitimer(ITIMER_REAL, &tout_val,0);

#ifdef	RTT_DEBUG
	rtt_debug(&rttinfo);
#endif

    if (sigsetjmp(jmpbuf, 1) != 0) 
    {
		if (rtt_timeout(&rttinfo) < 0) 
        {
			err_msg("dg_send_recv: no response from server, giving up");
			rttinit = 0;	// reinit in case we're called again 
			errno = ETIMEDOUT;
			return(-1);
		}
#ifdef	RTT_DEBUG
        rtt_debug(&rttinfo);
		err_msg("dg_send_recv: timeout, retransmitting");
#endif
		goto sendagain;
	}

	do {
		n = recv(fd, &recvhdr, sizeof(recvhdr), flags); 
#ifdef	RTT_DEBUG
		fprintf(stderr, "recv %4d\n", recvhdr.ack_num);
#endif
	} while (recvhdr.ack_num != dg_ptr->seq_num);

	/* top SIGALRM time
		 4calculate & store new RTT estimator values */

    tout_val.it_value.tv_sec = 0;
    tout_val.it_value.tv_usec = 0; 
	
    setitimer(ITIMER_REAL, &tout_val,0);
	
	rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.tstamp);

	return(n - sizeof(datagram));	/* return size of received datagram */
}

static void
sig_alrm(int signo)
{
    log_msg("sig alarm");
	siglongjmp(jmpbuf, 1);
}

ssize_t
Dg_send_recv(int fd, datagram* dg_ptr, int flags, datagram_list *head)
{
	ssize_t	n;
	n = dg_send_recv(fd, dg_ptr, flags, head);
	if (n < 0)
		err_quit("dg_send_recv error");

	return(n);
}
